package com.shaozi.nc.manage.secretary;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import com.shaozi.data.mongo.model.ModelBase;
import com.shaozi.data.mq.business.bus.translation.HandleByPushType;
import com.shaozi.lib.consts.CoreConstants;
import com.shaozi.lib.core.StatusCode;
import com.shaozi.lib.manage.ManageBase;
import com.shaozi.lib.throwable.SzException;
import com.shaozi.nc.bean.resp.ReqListSecretaryBean;
import com.shaozi.nc.bean.resp.ReqMakeSecretaryReadByIdsBean;
import com.shaozi.nc.bean.resp.ReqMessageSetReadForTypeBean;
import com.shaozi.nc.bean.resp.ReqSecretaryTypeBadgeBean;
import com.shaozi.nc.bean.resp.ReqSecretaryUnreadMessageTotalBean;
import com.shaozi.nc.bean.resp.RespBaseTypeBadgeBean;
import com.shaozi.nc.bean.resp.RespMessageSetReadForTypeBean;
import com.shaozi.nc.data.model.SecretaryModel;
import com.shaozi.nc.data.mongodao.BaseSecretaryMDao;
import com.shaozi.nc.manage.secretary.bean.UpdateUserReadBean;
import com.shaozi.nc.mq.producer.SecretaryTextProducer;
import com.shaozi.nc.utils.SecretaryHelper;
import com.shaozi.utils.common.BeanUtils;

public abstract class BaseSecretaryManage<T extends ModelBase> extends ManageBase implements HandleByPushType {

	protected static int Type_secretary = 1;
	protected static int Type_briefReport = 2;

	private Logger log = Logger.getLogger(SecretaryManage.class);

	/**
	 * 根据pushtype指定，保存并发送
	 * 
	 * @param models
	 * @throws SzException
	 */
	@Override
	public List handleByPushType(String companyId, List models) throws SzException {
		if (models == null)
			return null;
		if (models.isEmpty())
			return null;
		List<SecretaryModel> saves = getSecretaryModelsByPushType(models,
				new Integer[] { SecretaryModel.PushType_Need_Save, SecretaryModel.PushType_NoNeed_Save });
		saveModels(companyId, saves);

		List<SecretaryModel> pushes = getSecretaryModelsByPushType(models,
				new Integer[] { SecretaryModel.PushType_Need_NoSave, SecretaryModel.PushType_Need_Save });
		unSetSecretary(pushes);
		SecretaryTextProducer secretaryTextProducer = (SecretaryTextProducer) BeanUtils
				.getBean("secretaryTextProducer");
		secretaryTextProducer.push(companyId, pushes);
		int size = pushes == null ? 0 : pushes.size();
		log.debug("push secretary size 2:" + size);
		return pushes;
	}

	@Deprecated
	public Map getTypeBadge(ReqSecretaryTypeBadgeBean reqBean) throws SzException {
		boolean ok = commonGetTypeBadge(reqBean);
		if (!ok) {
			return null;
		}
		return onServer().getTypeBadge(reqBean);
	}

	private boolean commonGetTypeBadge(ReqSecretaryTypeBadgeBean reqBean) {
		if (StringUtils.isEmpty(reqBean.getCompanyId()))
			return false;
		String[] types = SecretaryHelper.transType(reqBean.getModuleTypes());
		reqBean.setModuleTypes(types);
		return true;
	}

	public RespBaseTypeBadgeBean unreadMessageTotal(ReqSecretaryUnreadMessageTotalBean reqBean) throws SzException {
		if (StringUtils.isEmpty(reqBean.getCompanyId()))
			return null;
		return onServer().unreadMessageTotal(reqBean);
	}

	/**
	 * 
	 * @param reqBean
	 * @return
	 * @throws SzException
	 */
	public boolean makeSecretaryRead(ReqMakeSecretaryReadByIdsBean reqBean, RespMessageSetReadForTypeBean respBean)
			throws SzException {
		if (StringUtils.isEmpty(reqBean.getCompanyId()))
			return false;
		return onServer().makeSecretaryRead(reqBean.getCompanyId(), reqBean.getId(), reqBean.getUserId(), respBean);
	}

	public boolean makeSecretaryRead(ReqMessageSetReadForTypeBean reqBean, RespMessageSetReadForTypeBean respBean)
			throws SzException {
		return onServer().makeSecretaryRead(reqBean, respBean);
	}

	public boolean makeSecretaryReadByObserver(ReqMakeSecretaryReadByIdsBean reqBean,
			RespMessageSetReadForTypeBean respBean, UpdateUserReadBean bean) throws SzException {
		if (bean == null)
			return false;
		return onServer().updateUserRead(respBean, bean.getExtraIds(), bean.getSourceType(), bean.getUserId(),
				bean.getCompanyId());

	}

	public boolean makeSecretaryReadByObserver(ReqMessageSetReadForTypeBean reqBean,
			RespMessageSetReadForTypeBean respBean, UpdateUserReadBean bean) throws SzException {
		if (bean == null)
			return false;
		return onServer().updateUserRead(respBean, bean.getExtraIds(), bean.getSourceType(), bean.getUserId(),
				bean.getCompanyId());

	}

	public SecretaryModel getById(String companyId, String _id) throws SzException {
		return onServer().getById(companyId, _id);
	}

	public void saveModel(SecretaryModel model) throws SzException {
		if (model == null)
			return;

		initModel(model);
		onServer().saveModel(model);
	}

	public void saveModels(String companyId, List<SecretaryModel> models) throws SzException {
		if (models == null)
			return;
		for (int i = 0; i < models.size(); i++) {
			initModel(models.get(i));
		}
		onServer().saveModels(companyId, models);
	}

	private List<SecretaryModel> getSecretaryModelsByPushType(List<SecretaryModel> models, Integer[] pushTypes) {
		if ((pushTypes == null) || (pushTypes.length == 0))
			return models;
		List<SecretaryModel> ret = new ArrayList<>(models.size());
		List<Integer> pushTypeList = Arrays.asList(pushTypes);
		models.forEach((model) -> {
			pushTypeList.forEach((pt) -> {
				if ((int) model.getPushType() == (int) pt) {
					ret.add(model);
				}
			});
		});
		return ret;
	}

	private void unSetSecretary(List<SecretaryModel> models) {
		if (models == null)
			return;
		for (SecretaryModel model : models) {
			if (model.getCreateTime() == null) {
				model.setCreateTime(System.currentTimeMillis());
			}
			// model.setCreateTime(null);
			model.setIsDel(null);
			model.setUpdateTime(null);
			model.setDelTime(null);
		}
	}

	private void initModel(SecretaryModel model) {
		long nowTime = System.currentTimeMillis();
		if (StringUtils.isEmpty(model.getId())) {
			if (model.getCreateTime() == null)
				model.setCreateTime(nowTime);
		}
		if (model.getIsDel() == null)
			model.setIsDel(0);
		model.setUpdateTime(nowTime);
		if (model.getUsers() != null) {
			model.getUsers().forEach((user) -> {
				user.setCreateTime(nowTime);
				user.setUpdateTime(nowTime);
			});
		}
	}

	public List<SecretaryModel> listUpdateObjects(ReqListSecretaryBean reqList) throws SzException {
		if (reqList == null)
			throw new SzException(StatusCode.Code_RPC_ReqParam_Error, "request param error");

		if (StringUtils.isEmpty(reqList.getCompanyId()))
			throw new SzException(StatusCode.Code_RPC_CompanyId_Lost, "company id lost");

		if (StringUtils.isEmpty(reqList.getUserId())) {
			throw new SzException(StatusCode.Code_RPC_UserId_Lost, "user id lost");
		}
		if ((reqList.getTimestamp() == null) || (reqList.getTimestamp() == 0l)) {
			reqList.setTimestamp(System.currentTimeMillis());
			reqList.setDirect(ReqListSecretaryBean.Direct_Old);
		}
		if (reqList.getDirect() == null) {
			reqList.setDirect(ReqListSecretaryBean.Direct_New);
		}
		if (reqList.getLimit() == null) {
			reqList.setLimit(0);
		}
		if ((reqList.getDirect() == ReqListSecretaryBean.Direct_Old) && (reqList.getLimit() == 0)) {
			reqList.setLimit(CoreConstants.DEF_PAGESIZE);
		}
		if (reqList.getSkip() == null)
			reqList.setSkip(0);
		return onServer().listUpdateObjects(reqList);
	}

	public long getMaxUpdateTime(String compId, String userId, Integer isRead) throws SzException {
		return onServer().getMaxUpdateTime(compId, userId, isRead);

	}

	public abstract <T extends ModelBase> BaseSecretaryMDao<T> onServer();
}
